import React, { useEffect, useState } from 'react';
import moment, { Duration } from 'moment';
import { Howl, Howler } from 'howler';
import { Avatar, Icon, Popover, Slider, Typography } from 'antd';
import { PersonalRadioItem } from '@/domains/radio';
import { useInterval } from '@/utils/utils';

import styles from './index.less';

interface Props {
  data: PersonalRadioItem | null;
  onPrev: () => void;
  onNext: () => void;
}

const asmDuration = (seek: number) => {
  const time: Duration = moment.duration(seek, 'seconds');
  const minutes = time.get('minutes') || 0;
  const seconds = time.get('seconds') || 0;
  return `${minutes < 10 ? `0${minutes}` : minutes}:${seconds < 10 ? `0${seconds}` : seconds}`;
};

const Audio: React.FC<Props> = props => {
  const { data, onPrev, onNext } = props;
  const [sound, setSound] = useState();
  const [seek, setSeek] = useState(0);
  const [duration, setDuration] = useState(0);
  const [showVol, setShowVol] = useState(false);
  const [volume, setVolume] = useState(Number(localStorage.getItem('volume') || 50));
  const [loading, setLoading] = useState(true);
  const [playBtn, setPlayBtn] = useState(false);
  const [pauseBtn, setPauseBtn] = useState(false);

  const setBtnStatus = (_loading: boolean, _playBtn: boolean, _pauseBtn: boolean) => {
    setLoading(_loading);
    setPlayBtn(_playBtn);
    setPauseBtn(_pauseBtn);
  };

  const doPlay = () => {
    sound && sound.play();
  };

  const doPause = () => {
    sound && sound.pause();
  };

  const doSeek = (per: number) => {
    sound && sound.seek(per);
    setSeek(per);
  };

  const changeVol = (per: number) => {
    Howler.volume(volume / 100);
    localStorage.setItem('volume', String(per));
    setVolume(per);
  };

  useEffect(() => {
    Howler.volume(volume / 100);
    return () => {
      Howler.unload();
    };
  }, []);

  useEffect(() => {
    Howler.unload();
    setSeek(0);
    setDuration(0);
    if (data) {
      setSound(
        new Howl({
          src: data.audio || '',
          html5: true,
          autoplay: true,
          format: ['mp3', 'aac'],
          onload: () => setBtnStatus(false, true, false),
          onplay: () => setBtnStatus(false, false, true),
          onpause: () => setBtnStatus(false, true, false),
          onend: () => {
            setBtnStatus(false, true, false);
            setSeek(0);
          },
          onstop: () => {},
          onseek: () => {},
        }),
      );
    }
  }, [data]);

  useInterval(() => {
    if (sound) {
      if (sound.playing()) {
        setSeek(sound.seek());
      }
      if (sound.state() === 'loaded') {
        setDuration(sound.duration());
      } else {
        setBtnStatus(true, false, false);
      }
    }
  }, 1000);

  return (
    <div className={styles.wrapper}>
      <div className={styles.control}>
        <div className={styles.btnGroup}>
          <Icon className={styles.btn} onClick={onPrev} type="step-backward" />
          {playBtn && <Icon className={styles.btn} onClick={doPlay} type="caret-right" />}
          {pauseBtn && <Icon className={styles.btn} onClick={doPause} type="pause" />}
          {loading && <Icon className={styles.btn} type="loading" />}
          <Icon className={styles.btn} onClick={onNext} type="step-forward" />
        </div>
        {data && (
          <div className={styles.metaWrapper}>
            <Avatar className={styles.metaAvatar} src={data.banner} />
            <div className={styles.metaInfo}>
              <Typography.Text className={styles.metaTitle} ellipsis>
                {data.title}
              </Typography.Text>
              <Typography.Text className={styles.metaDesc} ellipsis>
                {data.description}
              </Typography.Text>
            </div>
          </div>
        )}
        <Popover
          content={
            <Slider
              className={styles.volumeBar}
              vertical
              value={volume}
              onChange={value => changeVol(value as number)}
            />
          }
          visible={showVol}
          placement="topRight"
          trigger="click"
        >
          <Icon className={styles.btn} onClick={() => setShowVol(!showVol)} type="sound" />
        </Popover>
      </div>
      <div className={styles.progress}>
        <div className={styles.seek}>{asmDuration(seek)}</div>
        <Slider
          className={`audioProgressBar ${styles.progressBar}`}
          value={seek}
          max={duration}
          tipFormatter={asmDuration}
          disabled={duration === 0 || duration === Infinity}
          onChange={value => doSeek(value as number)}
        />
        <div className={styles.duration}>{asmDuration(duration)}</div>
      </div>
    </div>
  );
};

export default Audio;
